package com.swt.agy.backend.utils;

import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @Auther: yxd
 * @Date: 2019/4/12 15:08
 * @Description:
 * @Version: V1.0
 */
@Slf4j
public class DateUtils {

    private static final String LONG_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static final String SHORT_DATE_FORMAT = "yyyy-MM-dd";

    /**
     * 返回某天开始时间点
     * @return
     */
    public static Date startTimeOfCurrentDay(Date date) {
        Calendar todayStart = Calendar.getInstance();
        if (null != date) {
            todayStart.setTime(date);
        }

        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);

        return todayStart.getTime();
    }

    /**
     * 返回某天结束时间
     * @eturn
     */
    public static Date endTimeOfCurrentDay(Date date) {
        Calendar todayEnd = Calendar.getInstance();
        if (null != date) {
            todayEnd.setTime(date);
        }
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime();
    }

    public  static  Date startTimeOfThisYear(Date date){
        Calendar thisYear = Calendar.getInstance();
        if (null != date) {
            thisYear.setTime(new Date());
        }
        thisYear.set(Calendar.MONTH, 0);
        thisYear.set(Calendar.DATE, 1);
        thisYear.set(Calendar.HOUR_OF_DAY, 0);
        thisYear.set(Calendar.MINUTE, 0);
        thisYear.set(Calendar.SECOND, 0);
        thisYear.set(Calendar.MILLISECOND, 0);
        return thisYear.getTime();
    }

    /**
     * 获取两个时间点之间的时间集合，跨度是range
     * @param startDate
     * @param endDate
     * @param type
     * @return
     */
    public static List<Date> getDateStart2End(Date startDate, Date endDate, int type, boolean containFirst) {
        Calendar cd = Calendar.getInstance();
        List<Date> list = new ArrayList<Date>();
        Date date =startDate;
        while (date.getTime() <= endDate.getTime()){
            list.add(date);
            cd.setTime(date);
            cd.add(type, 1);
            date = cd.getTime();
        }
        // 不包含最开始的那一个时间，如果不包含，但是时间段=1，直接返回
        if (!containFirst && list.size() > 1) {
            return new ArrayList<>(list.subList(1, list.size()));
        }
        return list;
    }

    /**
     * 返回当前时间或者处于之前或者之后的时间
     * +7表示后七天
     * -7表示前七天
     * @param type
     * @param amount
     * @return
     */
    public static Date getDate(int type, int amount) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(new Date());
        ca.add(type, amount);
        return ca.getTime();
    }

    /**
     * 返回时间或者处于之前或者之后的时间
     * +7表示后七天
     * -7表示前七天
     * @param type
     * @param amount
     * @return
     */
    public static Date getSomeDate(Date date, int type, int amount) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.add(type, amount);
        return ca.getTime();
    }

    /**
     * 获取传入日期所在月份的第一天
     * @param date
     * @return
     */
    public static Date getFirstDayOfMonth(Date date) {
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        final int last = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, last);
        return cal.getTime();
    }

    /**
     * 获取传入日期所在月份的最后一天
     * @param date
     * @return
     */
    public static Date getLastDayOfMonth(Date date) {
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        final int last = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, last);
        return cal.getTime();
    }

    /**
     * 获取月份，从1开始
     * @param date
     * @return
     */
    public static String getMonth(Date date) {
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return (cal.get(Calendar.MONTH) + 1) + "";
    }

    /**
     * 格式化输出
     * @param date
     * @param pattern
     * @return
     */
    public static String formatDate(Date date, String pattern) {

        return getSimpleDateFormat(pattern).format(date);
    }

    /**
     * 字符串转换Date
     * @param date
     * @param pattern
     * @return
     */
    public static Date parseDate(String date, String pattern) {
        try {
            return getSimpleDateFormat(pattern).parse(date);
        } catch (ParseException e) {
           log.error("日期转换错误", e);
        }
        return null;
    }

    /**
     * 获取月份集合，返回String集合
     * @param date
     * @return
     */
    public static List<String> getYearMonths(Date date, String pattern) {
        List<String> list = new ArrayList<String>();
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        for (int i = 0; i < 12; i++) {
            cal.set(Calendar.MONTH, i);
            list.add(formatDate(cal.getTime(), pattern == null ? "yyyy-MM" : pattern));
        }
        return list;
    }

    private static SimpleDateFormat getSimpleDateFormat(String pattern) {
        SimpleDateFormat sdf = null ;
        if (null == pattern || "".equals(pattern)) {
            sdf =new SimpleDateFormat(LONG_DATE_FORMAT);
        }
        sdf = new SimpleDateFormat(pattern);
        return sdf;
    }

    /**
     * 返回指定时长的毫秒数
     * @param hour
     * @return
     */
    public static long getMillSecond(int hour) {
        return hour * 60 * 60 * 1000;
    }

    /**
     * 获取该日期当前年份的第一天日期
     * @param date
     * @return
     */
    public static Date getYearFirstDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int currentYear = calendar.get(Calendar.YEAR);
        calendar.clear();
        calendar.set(Calendar.YEAR, currentYear);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    /**
     * 获取该日期当前年份的最后一天日期
     * @param date
     * @return
     */
    public static Date getYearLastDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int currentYear = calendar.get(Calendar.YEAR);
        calendar.clear();
        calendar.set(Calendar.YEAR, currentYear);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    /**
     * 计算两个时间之间的跨度:天
     * @param startTime
     * @param endTime
     * @return
     */
    public static long rangeDate(Date startTime, Date endTime) {
        long start = startTime.getTime();
        long end = endTime.getTime();
        long day = 1000 * 60 * 60 * 24;
        return (end - start) / day;
    }

    /**
     * 获取date所在季度的开始月份：1开始
     * @param date
     * @return
     */
    public static int getStartSeasonMonthDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        int season = (calendar.get(Calendar.MONTH) + 1) / 3;
        int result = 0;
        switch (season) {
            case 0 :
                result = 1;
                break;
            case 1 :
                result = 4;
                break;
            case 2 :
                result = 7;
                break;
            case 3 :
                result = 10;
                break;
        }
        return result;
    }

    /**
     * 获取date所在季度的结束月份：1开始
     * @param date
     * @return
     */
    public static int getEndSeasonMonthDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int season = (calendar.get(Calendar.MONTH) + 1) / 3;
        int result = 0;
        switch (season) {
            case 0 :
                result = 3;
                break;
            case 1 :
                result = 6;
                break;
            case 2 :
                result = 9;
                break;
            case 3 :
                result = 12;
                break;
        }
        return result;
    }

    public static void main(String[] args) {
        System.out.println(rangeDate(new Date(), new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24)));
        System.out.println(DateUtils.formatDate(DateUtils.getSomeDate(new Date(), Calendar.YEAR, -5), "yyyyMMddHHmmss"));
    }
}
